*! version 2.24 (14May2023), by Mead Over
*! Enhanced version of -grc1leg- version 1.0.5  02jun2010, by Vince Wiggins
program grc1leg2
	version 13.1
	syntax [anything(id="graph list")] [, LEGendfrom(string)				///
			     POSition(string) RING(integer -1) SPAN	///
			     NAME(passthru) SAVing(string asis)   ///
				 XTOB1title XTItlefrom(string) XTSize(string)  ///  These and following options by MO
				 LABSize(string) LSize(string)  ///  lsize() is retained fo backward compatibility
				 YTOL1title y1tol1title YTItlefrom(string) YTSize(string)  ///
				 y2tor1title y2titlefrom(string) y2tsize(string)  ///
				 l1tol1title l1titlefrom(string)  ///
				 l2tol2title l2titlefrom(string)  ///
				 r1tor1title r1titlefrom(string)  ///
				 r2tor2title r2titlefrom(string)  ///
				 MAINTOtoptitle MAINTItlefrom(string) MAINFrom(string) MTSize(string)  ///  
				 SUBTOsubtitle SUBFrom(string) STSize(string)  ///  
				 NOTETOnote SUBTONote NOTEFrom(string) NTSize(string)  ///  
				 SYMXsize(string) SYMYsize(string) LMSize(string) /// 
				 LTItle(string) LTSize(string) LSUBTItle(string) LSUBTSize(string)  ///
				 LEGScale(string)  ///
				 LXOffset(real 0) LYOffset(real 0) LOFF HIDElegendfrom  ///
				 LCols(string) LRows(string) LHoles(string)  ///
				 ysize(passthru) xsize(passthru) margins(passthru) scale(passthru) scheme(passthru) ///
				 holes(string) ///
				 GRAPHon DOTS DEBUG notrap noAUTOsize * ]
				 
	if strpos(`"`anything'"',"*") | strpos(`"`anything'"',"?") {
	    di as err `"The "wildcard" characters "*" and "?" are not permitted in the list of graph names to be combined."'
		error 198
	}

	local Npnls : list sizeof anything
	if "`holes'"~="" {
		local Nholes : list sizeof holes
		local Npnls = `Npnls' + `Nholes'
		local holes holes(`holes')
	}

					//  For compatibility with version 2.13, allow only one or neither of following two options
	local opt1 = cond("`maintitlefrom'"~="","maintitlefrom()","")
	local opt2 = cond("`mainfrom'"~="","mainfrom()","") 
	opts_exclusive "`opt1' `opt2'"  //  Allow only one of these options
	local mainfrom `maintitlefrom'`mainfrom'
	if "`mainfrom'"~=""   local maintotoptitle maintotoptitle
		
	if "`dots'"=="dots"  {
	    nois _dots 0, title(-grc1leg2- working...)
		global grc1leg2_stage 1
	}
	else {
		di as txt "-grc1leg2- working..."
	}
	if strpos(`"`saving'"',"asis") {
		local isasis isasis
	}
	
					// If -grc1leg2- has previously set graphics off,
					// and exited without setting graphics back on,
					// set graphics on now.
	if "${grc1leg2_set_graph}"=="off" {
	    set graphics on
		global grc1leg2_set_graph 
	}
	local usergrset "`c(graphics)'"
	if "`graphon'"=="" & "`usergrset'"=="on" {
	    set graphics off
		global grc1leg2_set_graph off
	}

	gr_setscheme , refscheme	// So we can have temporary styles

					// location and alignment in cell
	tempname clockpos
	if ("`position'" == "") local position 6
	.`clockpos' = .clockdir.new , style(`position')
	local location `.`clockpos'.relative_position'

					// specify -ring()- for combined legend
	if `ring' > -1 {
		if (`ring' == 0) {
			local location "on"
			local ring ""
		}
		else	local ring "ring(`ring')"
	}
	else	local ring ""

	if "`span'" != "" {
		if "`location'" == "above" | "`location'" == "below" {
			local span spancols(all)
		}
		else	local span spanrows(all)
	}

					// allow legend to be from any graph
	if `"`legendfrom'"' != "" {			
		local lfrom : list posof `"`legendfrom'"' in anything
		if `lfrom' == 0 {
		    di as err `"-`legendfrom'- not found in graph name list"'
		    error 198
		}
	}
	else {  		// use graph 1 for legend by default
		local lfrom 1
		gettoken legendfrom : anything   // Replace = word("`anything'",1) with -gettoken- in ver. 2.12
	}
	
	if "`dots'"=="dots"  make10dots , stage(${grc1leg2_stage})
	
	if "`debug'"~=""  {
		di _n as err "Executing -gr combine- on component graphs without display"
		di as err `"Options not parsed by -syntax- and passed through to -gr combine- are:"' ///
			_n `"`options'"'	_n
	}

	//	When editing component panels below, panels are identified by their sequence in this combined graph
	graph combine `anything' , `holes' `name' nodraw `options'  // combine graphs
	
	if "`name'" != "" {				// get graph name
		local 0 `", `name'"'
		syntax [, name(string) ]
		local 0 `"`name'"'
		syntax [anything(name=name)] [, replace]
	}
	else	local name Graph

	//  Options for -gr combine-
	if "`ysize'`xsize'`margins'`scale'`scheme'"~="" {
		graph display `name' , `ysize' `xsize' `margins' `scale' `scheme'
		graph rename `name' `name', replace
		if "`dots'"=="dots"  make10dots , stage(${grc1leg2_stage})
	}	

	//  Determine from which type of graph the legend is borrowed
	chk_legend `name' , lfrom(`lfrom') legendfrom(`"`legendfrom'"') `trap' `debug'  // Double quotes added ver. 2.12
		if "`debug'"~="" {
			di _n as err "The subroutine -chk_legend- returns:"
			return list
			matlist r(keystyledex)
		} 
		local Nkeys `r(Nkeys)'
		local Nlabels `r(Nlabels)'
		local labelwidth `r(labelwidth)'
		local legendtype `r(legendtype)'
		local legendclass `r(legendclass)'
		local NkeysEqNlabels `r(NkeysEqNlabels)'
		local NminofKeysLabels  `r(NminofKeysLabels)'
		local NmaxofKeysLabels  `r(NmaxofKeysLabels)'
		//  The matrix consisting of the value of -styledex- for all the legend keys
		tempname keystyledex
		mat define `keystyledex' = r(keystyledex)
		local SmlstEqLrgst = `r(SmlstEqLrgst)'
	
					// turn off legends & optionally titles, etc on component graphs
	forvalues i = 1/`Npnls' {
 	
					//  Suppress legend on a -combined- graph, version 1.34 
		forvalues g = 1/30 {
			cap classutil describe  .`name'.plotregion1.graph`i'.plotregion1.graph`g'.legend    
			if _rc == 0 {
				_gm_edit .`name'.plotregion1.graph`i'.plotregion1.graph`g'.legend.draw_view.set_false
				_gm_edit .`name'.plotregion1.graph`i'.plotregion1.graph`g'.legend.fill_if_undrawn.set_false
				_gm_edit .`name'.plotregion1.graph`i'.plotregion1.graph`g'.legend.draw_view.setstyle, style(no)
			}
			else {
				continue, break				
			}
		}
			
		cap classutil describe  .`name'.graphs[`i'].legend    
		if _rc == 0 {
			_gm_edit .`name'.graphs[`i'].legend.draw_view.set_false
			_gm_edit .`name'.graphs[`i'].legend.fill_if_undrawn.set_false
			//  Suppress legend on a -by- graph
			_gm_edit .`name'.graphs[`i'].legend.draw_view.setstyle, style(no)
		}

		cap classutil describe  .`name'.graphs[`i'].plotregion1.atlegend
		if _rc == 0 {
			_gm_edit .`name'.graphs[`i'].plotregion1.atlegend.draw_view.setstyle, style(no)
		}
		
		if "`xtob1title'"~="" {  // turn off xaxis1 titles  
			cap classutil describe  .`name'.graphs[`i'].xaxis1.title    
			if _rc == 0 {
				_gm_edit .`name'.graphs[`i'].xaxis1.title.draw_view.set_false
			}
		}
		if "`ytol1title'"~="" | "`y1tol1title'"~="" {  // turn off yaxis1 titles (by M. Over)
			cap classutil describe  .`name'.graphs[`i'].yaxis1.title    
			if _rc == 0 {
				_gm_edit .`name'.graphs[`i'].yaxis1.title.draw_view.set_false
			}
		}
		if "`l1tol1title'"~=""  {  // turn off l1 titles  
			cap classutil describe  .`name'.graphs[`i'].l1title    
			if _rc == 0 {
				_gm_edit .`name'.graphs[`i'].l1title.draw_view.set_false
			}
		}
		if "`y2tor1title'"~="" {  // turn off yaxis2 titles  
			cap classutil describe  .`name'.graphs[`i'].yaxis2.title    
			if _rc == 0 {
				_gm_edit .`name'.graphs[`i'].yaxis2.title.draw_view.set_false
			}
		}
		if "`r1tor1title'"~="" {  // turn off yaxis2 titles  
			cap classutil describe  .`name'.graphs[`i'].r1title    
			if _rc == 0 {
				_gm_edit .`name'.graphs[`i'].r1title.draw_view.set_false
			}
		}

			// suppress main title, subtitle and/or note in component panels
/*
Option:               Graph from and text size option names:
-maintotoptitle-      -maintitlefrom- or -mainfrom-, -mtsize()-
-subtosubtitle-       -subfrom-, -stsize()-
-notetonote-          -notefrom-, -ntsize()-
-subtotoptitle-       -maintitlefrom- or -mainfrom-  <--  Forget this
-maintosubtitle-      -mainfrom-                      <--  Forget this
-subtonote-           -subfrom-                      <--  But how about this???
*/

		foreach ttl in main sub note {
			
			local ttlopt =  ///
				cond("`ttl'"=="main","maintotoptitle", ///
				cond("`ttl'"=="sub","subtosubtitle", ///
				cond("`ttl'"=="note","notetonote","noneofabove")))
			
			local ttltype =  ///
				cond("`ttl'"=="main","title", ///
				cond("`ttl'"=="sub","subtitle", ///
				cond("`ttl'"=="note","note","noneofabove")))
				if "`ttltype'"=="noneofabove" {
					di as err "Error in grc1leg2, Line 237:  This error should never occur."
				}

			if "``ttlopt''"~="" {  // turn off `ttl' title
				cap classutil describe  .`name'.graphs[`i'].`ttltype'
				if _rc == 0 {
					_gm_edit .`name'.graphs[`i'].`ttltype'.draw_view.set_false
					_gm_edit .`name'.graphs[`i'].`ttltype'.fill_if_undrawn.set_false
				}
			}
		}

		if "`dots'"=="dots"  make10dots , stage(${grc1leg2_stage}) 
	}
	
	//  legend is from a single graph
	if "`legendtype'"=="legend"  {
								// insert overall legend
		.`name'.insert (legend = .`name'.graphs[`lfrom'].legend)	    ///
				`location' plotregion1 , `ring' `span' 

		_gm_log  .`name'.insert (legend = .graphs[`lfrom'].legend) 	    ///
				`location' plotregion1 , `ring' `span' 

	}
		
	//  if not and if legend is from -graph ..., by()- 
	//  (with -else- here ... , -grc1leg2- is recursive)
	else if "`legendtype'"=="atlegend"  {
								// insert overall legend
		.`name'.insert (legend = .`name'.graphs[`lfrom'].plotregion1.atlegend)	    ///
				`location' plotregion1 , `ring' `span' 

		_gm_log  .`name'.insert (legend = .graphs[`lfrom'].plotregion1.atlegend) 	    ///
				`location' plotregion1 , `ring' `span' 
	}

	//  if not and if legend is from -gr combine- 
	//  (and with -else- here, -grc1leg2- is recursive)
	else if "`legendtype'"=="combined"  {
								// insert overall legend
		.`name'.insert (legend = .`name'.plotregion1.graph`lfrom'.plotregion1.graph1.legend)	    ///
				`location' plotregion1 , `ring' `span' 

		_gm_log  .`name'.insert (legend = .plotregion1.graph`lfrom'.plotregion1.graph1.legend) 	    ///
				`location' plotregion1 , `ring' `span' 
	}

							//  Display combined legend
	_gm_edit .`name'.legend.style.box_alignment.setstyle ,		    ///
		style(`.`clockpos'.compass2style')

	_gm_edit .`name'.legend.draw_view.setstyle, style(yes)		
		
							// use -xtitlefrom- xtitle as overall b1title
	if "`xtob1title'"=="" & "`xtitlefrom'"~="" {
		local xtob1title xtob1title
	}
	if "`xtob1title'"~="" {
							// allow b1title to be from any graph
		if "`xtitlefrom'" != "" {			
			local xfrom : list posof "`xtitlefrom'" in anything
			if `xfrom' == 0 {
				di as error `"`xtitlefrom' not found in graph name list"'
				error 198
			}
		}
		else	local xfrom 1		// use graph 1 for xtitle by default

		.`name'.b1title = .`name'.graphs[`xfrom'].xaxis1.title
		_gm_log .`name'.b1title = .graphs[`xfrom'].xaxis1.title
		_gm_edit .`name'.b1title.draw_view.set_true
		
	}

							// use -ytitlefrom- ytitle as overall l1title
	if "`ytol1title'"=="" & "`ytitlefrom'"~="" {
		local ytol1title ytol1title
	}
	if "`ytol1title'"~="" {
							// allow l1title to be from any graph
		if "`ytitlefrom'" != "" {			
			local yfrom : list posof "`ytitlefrom'" in anything
			if `yfrom' == 0 {
				di as error `"`ytitlefrom' not found in graph name list"'
				error 198
			}
		}
		else	local yfrom 1		// use graph 1 for ytitle by default

		.`name'.l1title = .`name'.graphs[`yfrom'].yaxis1.title
		_gm_log .`name'.l1title = .graphs[`yfrom'].yaxis1.title
		_gm_edit .`name'.l1title.draw_view.set_true

	}

							// use -y2titlefrom-'s y2title as overall r1title
	if "`y2tor1title'"=="" & "`y2titlefrom'"~="" {
		local y2tor1title y2tor1title
	}
	if "`y2tor1title'"~="" {
							// allow r1title to be from any graph
		if "`y2titlefrom'" != "" {			
			local y2from : list posof "`y2titlefrom'" in anything
			if `y2from' == 0 {
				di as error `"`y2titlefrom' not found in graph name list"'
				error 198
			}
		}
		else	local y2from 1		// use graph 1 for ytitle by default

		.`name'.r1title = .`name'.graphs[`y2from'].yaxis2.title
		_gm_log .`name'.r1title = .graphs[`y2from'].yaxis2.title
		_gm_edit .`name'.r1title.draw_view.set_true

	}

	foreach t in l1 l2 r1 r2  {	
								// use -`t'titlefrom-'s `t'title as overall `t'title
		if "``t'to`t'title'"=="" & "``t'titlefrom'"~="" {
			local `t'to`t'title `t'to`t'title
		}
		if "``t'to`t'title'"~="" {
								// allow `t'title to be from any graph
			if "``t'titlefrom'" != "" {			
				local yfrom : list posof "``t'titlefrom'" in anything
				if `yfrom' == 0 {
					di as error `"``t'titlefrom' not found in graph name list"'
					error 198
				}
			}
			else	local yfrom 1		// use graph 1 for `t'title by default

			.`name'.`t'title = .`name'.graphs[`yfrom'].`t'title
			_gm_log .`name'.`t'title = .graphs[`yfrom'].`t'title
			_gm_edit .`name'.`t'title.draw_view.set_true

		}
	}
	
	foreach ttl in main sub note {
		
		local ttlopt =  ///
			cond("`ttl'"=="main","maintotoptitle",  ///
			cond("`ttl'"=="sub","subtosubtitle",  ///
			cond("`ttl'"=="note","notetonote","noneofabove")))
			
		if "``ttlopt''"=="" & "``ttl'from'"~="" {
			local `ttlopt' `ttlopt'
		}
		if "``ttlopt''"~="" {
								// allow `ttl' title to be from any graph
			if "``ttl'from'" != "" {			
				local `ttl'from : list posof "``ttl'from'" in anything
				if ``ttl'from' == 0 {
					di as error `"``ttl'from' not found in graph name list"'
					error 198
				}
			}
			else	local `ttl'from 1		// use graph 1 for `ttl' title by default

			local ttltype =  ///
				cond("`ttl'"=="main","title", ///
				cond("`ttl'"=="sub","subtitle", ///
				cond("`ttl'"=="note","note","noneofabove")))
			if "`ttltype'"=="noneofabove" {
				di as err "Error in grc1leg2, Line 402:  This error should never occur."
			}
			
			.`name'.`ttltype' = .`name'.graphs[``ttl'from'].`ttltype'
			_gm_log .`name'.`ttltype' = .graphs[``ttl'from'].`ttltype'
			_gm_edit .`name'.`ttltype'.draw_view.set_true

		}

	}

	_gm_edit .`name'.legend.draw_view.set_true

			// VW's code to maintain serset reference counts
			// must pick up sersets by reference, they were 
			// -.copy-ied when the legend was created above
	if "`legendtype'"=="legend"  {
		forvalues i = 1/`.`name'.legend.keys.arrnels' {
			if "`.`name'.legend.keys[`i'].view.serset.isa'" != "" {
				_gm_edit .`name'.legend.keys[`i'].view.serset.ref_n + 99

				.`name'.legend.keys[`i'].view.serset.ref = 		   ///
					.`name'.graphs[`lfrom'].legend.keys[`i'].view.serset.ref

				_gm_log  .`name'.legend.keys[`i'].view.serset.ref = 	   ///
					.graphs[`lfrom'].legend.keys[`i'].view.serset.ref
			}
			if "`.`name'.legend.plotregion1.key[`i'].view.serset.isa'" != "" {
				_gm_edit						   ///
					.`name'.legend.plotregion1.key[`i'].view.serset.ref_n + 99

				.`name'.legend.plotregion1.key[`i'].view.serset.ref =  ///
					.`name'.graphs[`lfrom'].legend.keys[`i'].view.serset.ref

				_gm_log							   ///
					.`name'.legend.plotregion1.key[`i'].view.serset.ref =  ///
					.graphs[`lfrom'].legend.keys[`i'].view.serset.ref
			}
			if "`dots'"=="dots"  make10dots , stage(${grc1leg2_stage})
		}
	}
	
			//  Fix the serset numbering when source is a -gr, by()- graph
	if "`legendtype'"=="atlegend"  {
		forvalues i = 1/`.`name'.legend.keys.arrnels' {
			if "`.`name'.legend.keys[`i'].view.serset.isa'" != "" {
				_gm_edit .`name'.legend.keys[`i'].view.serset.ref_n + 99
		
				.`name'.legend.keys[`i'].view.serset.ref = 		   ///
					.`name'.graphs[`lfrom'].plotregion1.atlegend.keys[`i'].view.serset.ref
	
				_gm_log  .`name'.legend.keys[`i'].view.serset.ref = 	   ///
					.graphs[`lfrom'].plotregion1.atlegend.keys[`i'].view.serset.ref
			}
			if "`.`name'.legend.plotregion1.key[`i'].view.serset.isa'" != "" {
				_gm_edit						   ///
					.`name'.legend.plotregion1.key[`i'].view.serset.ref_n + 99

				.`name'.legend.plotregion1.key[`i'].view.serset.ref =  ///
					.`name'.graphs[`lfrom'].plotregion1.atlegend.keys[`i'].view.serset.ref

				_gm_log							   ///
					.`name'.legend.plotregion1.key[`i'].view.serset.ref =  ///
					.graphs[`lfrom'].plotregion1.atlegend.keys[`i'].view.serset.ref
			}
			if "`dots'"=="dots"  make10dots , stage(${grc1leg2_stage})
		}
	}

			//  Fix the serset numbering when source is a -gr_combine- graph
	if "`legendtype'"=="combined"  {
		forvalues i = 1/`.`name'.legend.keys.arrnels' {
			if "`.`name'.legend.keys[`i'].view.serset.isa'" != "" {
				_gm_edit .`name'.legend.keys[`i'].view.serset.ref_n + 99
		
				.`name'.legend.keys[`i'].view.serset.ref = 		   ///
					.`name'.plotregion1.graph`lfrom'.plotregion1.graph1.legend.keys[`i'].view.serset.ref
	
				_gm_log  .`name'.legend.keys[`i'].view.serset.ref = 	   ///
					.plotregion1.graph`lfrom'.plotregion1.graph1.legend.keys[`i'].view.serset.ref
			}
			if "`.`name'.legend.plotregion1.key[`i'].view.serset.isa'" != "" {
				_gm_edit						   ///
					.`name'.legend.plotregion1.key[`i'].view.serset.ref_n + 99

				.`name'.legend.plotregion1.key[`i'].view.serset.ref =  ///
					.`name'.plotregion1.graph`lfrom'.plotregion1.graph1.legend.keys[`i'].view.serset.ref

				_gm_log							   ///
					.`name'.legend.plotregion1.key[`i'].view.serset.ref =  ///
					.plotregion1.graph`lfrom'.plotregion1.graph1.legend.keys[`i'].view.serset.ref
			}
			if "`dots'"=="dots"  make10dots , stage(${grc1leg2_stage})
		}
	}

	if "`dots'"=="dots" {
		make10dots , stage(${grc1leg2_stage})
		di _n
	}
	
	//  Suppress display of the combined legend
	if  "`loff'"~=""  {
		.`name'.legend.draw_view.setstyle, style(no)
		_gm_log .`name'.legend.draw_view.setstyle, style(no)
		
	}
	
	//  Modify the legend contents
	else {
	
		.`name'.legend.xoffset = `lxoffset'
		_gm_log .`name'.legend.xoffset = `lxoffset'

		.`name'.legend.yoffset = `lyoffset'
		_gm_log .`name'.legend.yoffset = `lyoffset'

		if "`ltitle'"~="" {
			.`name'.legend.title.text = {}
			.`name'.legend.title.text.Arrpush `ltitle'
			_gm_log .`name'.legend.title.text.Arrpush `ltitle'		
		}
		if "`lsubtitle'"~="" {
			.`name'.legend.subtitle.text = {}
			.`name'.legend.subtitle.text.Arrpush `lsubtitle'
			_gm_log .`name'.legend.subtitle.text.Arrpush `lsubtitle'
		}

		if "`lholes'"~="" {
			GetHoles , lholes(`lholes')
				local lholes `r(holes)'
			.`name'.legend.Edit , cmd(.holes = "`lholes'") keepstyles 
			_gm_log .`name'.legend.Edit , cmd(.holes = "`lholes'") keepstyles 
		}

		//  Don't draw the panel from which legend is borrowed
		//  Try to fill in the hole left by the undrawn panel.  Rarely works.
		if "`debug'"~=""  di as err _n "Number of panels (including holes) is: -`Npnls'-" 
		if  "`hidelegendfrom'"~=""  {
			opts_exclusive "`loff' `hidelegendfrom'"
			
			.`name'.plotregion1.graph`lfrom'.draw_view.setstyle, style(no)
			.`name'.plotregion1.graph`lfrom'.fill_if_undrawn.setstyle, style(no)

			_gm_log .`name'.plotregion1.graph`lfrom'.draw_view.setstyle, style(no)
			_gm_log .`name'.plotregion1.graph`lfrom'.fill_if_undrawn.setstyle, style(no)
			
			local Npnls = `Npnls' - 1
		}

		******  Resize legend elements  ******
		
		//  Default shrinking of legend
		if "`debug'"~=""  di as err _n "User supplied legend scale option is: -`legscale'-" 
		if "`legscale'"=="" {
			//	Default defined to be a multiplicative expresson such as *.7

			tempname scale_opts
			//  No. of panels             1   2   3   4   5   6   7   8   9  10  11  12
			matrix define `scale_opts' = [1, .8, .7, .7, .6, .6, .6, .6, .6, .4, .4, .4]
			
			local legscale = "*" + strofreal(cond(`Npnls'>12,.3,`scale_opts'[1,`Npnls']))
		}

		if "`debug'"~=""  {
			di as err _n "Legend scale option is set to: -`legscale'-" 
			di as err "Number of keys is: `Nkeys'"
			di as err "Number of labels is: `Nlabels'"
			di as err "NkeysEqNlabels is: `NkeysEqNlabels'"
			di as err "SmlstEqLrgst is: `SmlstEqLrgst'"
			di as err "labelwidth is: `labelwidth'"
			di as err "autosize is: `autosize'"
			di as err "legendclass is: `legendclass'"
			di as err "NminofKeysLabels is: `NminofKeysLabels'"
			di as err "legendtype is: `legendtype'"			
		}
		
		if "`autosize'"~="noautosize" {
			local opt1 = cond("`labsize'"~="","labsize","") 
			local opt2 = cond("`lsize'"~="","lsize","") 
			opts_exclusive "`opt1' `opt2'"  //  Allow only one of these options (lsize is retained for backward compatibility)
			local labsize `lsize'`labsize'
							
			if "`labsize'"=="" {
				local labsize `legscale'
			}
			.`name'.legend.Edit, style(labelstyle(size(`labsize')))
			_gm_log .`name'.legend.Edit, style(labelstyle(size(`labsize'))) 

			foreach xy in x y {
				if "`sym`xy'size'"=="" {
					local sym`xy'size  `legscale'
				}
				.`name'.legend.Edit, style(key_`xy'size(`sym`xy'size')) keepstyles 
				_gm_log .`name'.legend.Edit, style(key_`xy'size(`sym`xy'size')) keepstyles 
			}

			//  Allow resizing of markers in the legend only if they exist (_rc~=4018) & NminofKeysLabels > 0
			//	For example, neither -graph pie- nor -graph bar- has markers.
			if `NminofKeysLabels' > 0  {
				if "`lmsize'"=="" {
					local lmsize `legscale'
				}
				forvalues i = 1/`Nkeys' {
					cap .`name'.legend.plotregion1.key[`i'].view.style.editstyle marker(size(`lmsize')) editcopy

					//  Stata recovers from both errors 4018 and 4023
					if _rc > 0  & _rc ~= 4018 & _rc ~= 4023 {
						local exitrc = _rc
						// Trap if the markers of the specified component graph cannot be edited
						badlegend , lfrom(`lfrom') legendfrom(`"`legendfrom'"') exitrc(`exitrc') `trap'
					}
					else {
						_gm_log .`name'.legend.plotregion1.key[`i'].view.style.editstyle marker(size(`lmsize')) editcopy
					}
				}
			}
			//  When legend is not "complete, `NminofKeysLabels' == 0
			else /* if `"`labsize'`lmsize'`symxsize'`symysize'"'~= "" */ {
					
				di as txt `"Warning: Because the legend borrowed for the combined graph is not "complete","' /// 
					_n "automatic resizing of legend markers is disabled and {cmd:grc1leg2} ignores the option -lmsize-."  ///
					_n `"See the discussion of "known issues" in {cmd:grc1leg2}'s help file {help grc1leg2##known:here}."'
			}

			if "`ltsize'"=="" {
				local ltsize `legscale'
			}
			.`name'.legend.title.style.editstyle size(`ltsize') editcopy
			_gm_log .`name'.legend.title.style.editstyle size(`ltsize') editcopy

			if "`lsubtsize'"=="" {
				local ltsize `lsubtsize'
			}
			.`name'.legend.subtitle.style.editstyle size(`lsubtsize') editcopy
			_gm_log .`name'.legend.subtitle.style.editstyle size(`lsubtsize') editcopy

		}
		
		//  Resize the overall titles only with options, not automatically
		if  "`xtob1title'"~="" & "`xtsize'"~=""  {
			.`name'.b1title.style.editstyle size(`xtsize') editcopy
			_gm_log .`name'.b1title.style.editstyle size(`xtsize') editcopy
		}
		if  ("`ytol1title'"~="" | "`l1tol1title'"~="") & "`ytsize'"~=""  {
			.`name'.l1title.style.editstyle size(`ytsize') editcopy
			_gm_log .`name'.l1title.style.editstyle size(`ytsize') editcopy
		}
		if  ("`y2tor1title'"~="" | "`r1tor1title'"~="") & "`y2tsize'"~=""  {
			.`name'.r1title.style.editstyle size(`y2tsize') editcopy
			_gm_log .`name'.r1title.style.editstyle size(`y2tsize') editcopy
		}
		if  "`maintotoptitle'"~="" & "`mtsize'"~=""  {
			.`name'.title.style.editstyle size(`mtsize') editcopy
			_gm_log .`name'.title.style.editstyle size(`mtsize') editcopy
		}
		if  "`subtosubtitle'"~="" & "`stsize'"~=""  {
			.`name'.subtitle.style.editstyle size(`stsize') editcopy
			_gm_log .`name'.subtitle.style.editstyle size(`stsize') editcopy
		}
		if  "`notetonote'"~="" & "`ntsize'"~=""  {
			.`name'.note.style.editstyle size(`ntsize') editcopy
			_gm_log .`name'.note.style.editstyle size(`ntsize') editcopy
		}

	**** Rearranging the rows and columns of the borrowed legends using options -lcols()- and -lrows()-
	**** Logging these changes with _gm_log is not sufficient to assure they are preserved in a saved .gph file
		if "`lcols'"~="" | "`lrows'"~=""  {
			chkrowcol , lrows("`lrows'") lcols("`lcols'")
			
			if "`lcols'"~="" {
				.`name'.legend.Edit, style(cols(`r(nrowsorcols)')) style(rows(0)) keepstyles 
				_gm_log .`name'.legend.Edit, style(cols(`r(nrowsorcols)')) style(rows(0)) keepstyles 
			}
			else {

				.`name'.legend.Edit, style(cols(0)) style(rows(`r(nrowsorcols)')) keepstyles 			
				_gm_log .`name'.legend.Edit, style(cols(0)) style(rows(`r(nrowsorcols)')) keepstyles 			
			}
			graph rename `name' `name', replace  // This line does not fix the saved file
			
			if "`isasis'"==""  {
				di _n as txt "Note: To preserve in a saved graphics file the legend's row and column rearrangements"  ///
					_n "made with the options -lrows()- and/or -lcols()-, specify the suboption -asis-"  ///
					_n "for the {help saving_option:saving()} option or for the {help gr save:graph save} command." _n
			}
		}
	}
	
	if "`graphon'"=="" {
	    set graphics `usergrset'
		global grc1leg2_set_graph
	}

	cap gr draw `name'					// redraw graph
	if _rc > 0 {
		// Trap if the -gr draw- fails, presumably because of a bad legend
		local exitrc = _rc
		badlegend , lfrom(`lfrom') legendfrom(`"`legendfrom'"') exitrc(`exitrc') `trap'
	}

	if `"`saving'"' != `""' {
		
		cap noi gr save `"`name'"' `saving' 
		if _rc>0 {
			di as err "-grc1leg2-'s {help saving_option:saving()} option has failed."
			if "`isasis'"==""  {
				di as err "Try specifying {help saving_option:saving(filename,asis)}" _n
			}
			exit _rc
		}
		gettoken fname : saving , parse(", ")
		if ("`lcols'"~="" | "`lrows'"~="") & "`isasis'"==""  {
			di as txt `"Warning: After using options -lrows()- or -lcols()-, a "live" .gph file"'  ///
				_n "saved to disk may not retain those edits.  To retain row/column configuration,"  ///
				_n "try specifying {help saving_option:saving(filename,asis)}"
		}
		di as txt `"To view and verify the .gph file saved to disk, click {stata graph use `"`fname'"':here}."'
	}


end  /* End of main -grc1leg2 program */

program GetHoles, rclass
	syntax , lholes(numlist ascending >0)
	
	return local holes `lholes'
end  /* End of subroutine -GetHoles-  */


program chkrowcol, rclass
	syntax , [lcols(string) lrows(string)]
	
	if "`lcols'"~="" & "`lrows'"~="" {
		di as err "Specify only one of the two options: lcols() lrows()"
		error 198
	}
	
	if "`lcols'"~="" {
		local rc cols
	}
	else {
		local rc rows
	}
	
	local rl`rc' = real("`l`rc''")
	cap confirm integer number `rl`rc''
	if _rc > 0  {
		di as err "The option -l`rc'()- requires an integer."
		exit 7
	}
	
	return scalar nrowsorcols = `rl`rc''
	
end  /* End of subroutine -chkrowcol-  */

prog define make10dots , rclass
	syntax [, stage(integer -1)]
	
	if `stage' < 0 {
	    di as err "Error in -grc1leg2-'s subroutine -make10dots-"
		exit 199
	}
	local start = `stage' + 1
	local end = `stage' + 10
	foreach dot of numlist `start'/`end' {
		nois _dots `dot' 0
	}
	global grc1leg2_stage `end'
end  /* End of subroutine -make10dots-  */

program badlegend
*	syntax:  badlegend , lfrom(`lfrom') legendfrom(`"`legendfrom'"') exitrc(`exitrc') `trap' 
	syntax , lfrom(string) legendfrom(string)  [notrap exitrc(integer 198)]

	di as err _n "The legend in graph #`lfrom', -`legendfrom'-, has too few keys"  ///
		_n "or some keys have been suppressed by, for example, the -legend(order())- suboption."
		
	if "`trap'" == "notrap" {
		di as err _n "Captured return code _rc = {stata search r(`exitrc'),local:r(`exitrc');}" _n
	}
	else {
		graph drop _all
		serset clear
		set graph on
		di as err _n "Possible remedies include specifying the option -noautosize-"  ///
			_n as err "or using a hidden auxiliary graph for the legend as demonstrated"  ///
			_n as err "in Examples 3.10 of the help file {help grc1leg2##ex_3_10:here}." _n
			
		di as err _n "-grc1leg2- has cleared the graph space by executing"  ///
			_n "-graph drop _all- and -serset clear- before exiting."  ///
			_n `"For further information, see the discussion "'  ///
			_n `"of "known issues" in {cmd:grc1leg2}'s help file {help grc1leg2##known:here}."' _n

		error `exitrc'
	}

end  /* End of subroutine -badlegend- */

prog define chk_legend, rclass
*	syntax:
*	chk_legend `name' , lfrom(`lfrom') legendfrom(`"`legendfrom'"') `trap' `debug'
	syntax      name  , lfrom(integer) legendfrom(string) [trap debug]

	local name `namelist'
	local exitrc 0
	
	if "`debug'"~= "" {
		local noi noisily
		di _n as err `"Description of the legend's "class" using -classutil describe-:"'
	}
	
	cap `noi'  classutil describe  .`name'.graphs[`lfrom'].legend
	if _rc == 0 {
		local legend legend
		local legendclass   .graphs[`lfrom'].legend
		local Nkeys       `.`name'`legendclass'.keys.arrnels'
		local Nlabels     `.`name'`legendclass'.labels.arrnels'
		local Nmap        `.`name'`legendclass'.map.arrnels'   
		local labelwidth  `.`name'`legendclass'.labelwidth.val'
		local  NminofKeysLabels = min(`Nkeys',`Nlabels')
		local  NmaxofKeysLabels = max(`Nkeys',`Nlabels')
	}
	cap `noi'  classutil describe  .`name'.graphs[`lfrom'].plotregion1.atlegend
	if _rc == 0 {
		local atlegend atlegend
		local legend 
		local legendclass   .graphs[`lfrom'].plotregion1.atlegend
		local Nkeys       `.`name'`legendclass'.keys.arrnels'
		local Nlabels     `.`name'`legendclass'.labels.arrnels'
		local Nmap        `.`name'`legendclass'.map.arrnels'   
		local labelwidth  `.`name'`legendclass'.labelwidth.val'
		local  NminofKeysLabels = min(`Nkeys',`Nlabels')
		local  NmaxofKeysLabels = max(`Nkeys',`Nlabels')
	}
	cap `noi'  classutil describe  .`name'.plotregion1.graph`lfrom'.plotregion1.graph1.legend
	if _rc == 0 {
		local combined combined
		local legend 
		local atlegend 
		local legendclass   .plotregion1.graph`lfrom'.plotregion1.graph1.legend
		local Nkeys       `.`name'`legendclass'.keys.arrnels'
		local Nlabels     `.`name'`legendclass'.labels.arrnels'
		local Nmap        `.`name'`legendclass'.map.arrnels'   
		local labelwidth  `.`name'`legendclass'.labelwidth.val'
		local  NminofKeysLabels = min(`Nkeys',`Nlabels')
		local  NmaxofKeysLabels = max(`Nkeys',`Nlabels')
	}
	if ("`legend'"=="legend") + ("`atlegend'"=="atlegend") + ("`combined'"=="combined") > 1 {
		//  Type -combined- overrides type -atlegend-, which overrides type -legend-
		di as err "Legend types are " as res "`legend'" "`atlegend'" "`combined'"
		di as err "The legend is of more than one type.  This error should never occur."
		local exitrc 198
	}

	if ("`legend'"=="legend") + ("`atlegend'"=="atlegend") + ("`combined'"=="combined") ==0  {
		badlegend , lfrom(`lfrom') legendfrom(`"`legendfrom'"') `trap'   // Double quotes added ver. 2.12
	}
	
	//  Hypothesis: 
	//    Resizing legend elements fails when the values of -styledex- vary over the keys
	//    If so, detecting variation among the -styledex- values could be a way to trap 
	//    prior use of a legend(order())- option which prevents -gr draw- 
	//    from constructing the combined graph and thus crashes Stata and scrambles the sersets.
	tempname keystyledex
	local smallest  .
	local largest -9999999999
	foreach key of numlist 1/`Nkeys' {
		cap classutil describe .`name'`legendclass'.keys[`key'].pos.styledex
		if _rc==0 {
			local this_styledex `.`name'`legendclass'.keys[`key'].pos.styledex'
			mat define `keystyledex' = (nullmat(`keystyledex') , `this_styledex')
			local smallest = min(`this_styledex', `smallest')
			local largest  = max(`this_styledex', `largest')
			local cnms `cnms' key`key'
			mat colnames `keystyledex' = `cnms'
		}
	}
	
	return matrix keystyledex = `keystyledex'
	return scalar smallest = `smallest'
	return scalar largest = `largest'
	return local  SmlstEqLrgst = `smallest' == `largest'
		
	return local  legendtype `legend'`atlegend'`combined'
	return local  legendclass  `legendclass'
	return local  NkeysEqNlabels = (`Nkeys' == `Nlabels')
	return local  NminofKeysLabels  `NminofKeysLabels'
	return local  NmaxofKeysLabels  `NmaxofKeysLabels'
	foreach lcl in Nkeys Nlabels Nmap {
		confirm integer number ``lcl''
		return scalar `lcl' = ``lcl''
	}
	confirm number `labelwidth'
	return scalar labelwidth = `labelwidth'	
	
	if `exitrc'> 0 & "`trap'"=="" {
		error `exitrc'
	}

end	  /* End of subroutine chk_legend */
exit

* Version 1.0.5 (21feb2015): renamed for packaging with AIDSCost (no other changes)
* Version 1.1.0 (30mar2016): add the -xtob1title- and -xtitlefrom()- options
* Version 1.1.1 (1apr2016): make -xtitlefrom()- imply the -xtob1title- option
* Version 1.1.2 (8apr2016): Attempt to add a size option to the legend
*	The value of the option -lsize- appears in the graph editor under
*	legend/properties/labels/size, but has no effect on the actual size of the labels
* Version 1.1.3 (11apr2016): Incorporates Derek Wagner's suggestion for how 
*	to add a size option to the legend (Subsequently deprecated)
* Version 1.1.4 (12apr2016): Fixes bug in xtitlefrom() option
* Version 1.2  (11nov2019): Implement options -ytol1title- and -maintotoptitle-
* Version 1.3  (23Jan2021): Fix the option -lsize- and rename it -LABSize-
*	Add the legend options: SYMXsize, SYMYsize, LCOLS, LROWS, LHoles, 
*	LTItle, LTSize, LSUBTItle, LSUBTSize, LXOffset, LYOffset, LOFF,
* Version 1.31 (29Jan2021): Add options XTSize, YTSize, MTSize
* Version 1.32 (29Jan2021): Add error trap when -legendfrom- graph has no legend (lines 61, 72)
* Version 1.33 (12Mar2021): Add options -y2tor1title- & -y2titlefrom(name)- and -y2tsize- to move and re-size titles on the right y2-axis
* Version 1.40 (24Mar2021): Enable legend relocation from a -gr combine- or a -gr,by()- graph
* Version 1.41 (26Mar2021): Fix bug in options -lcols()- and -lrows()-
* Version 1.42 (29Mar2021): Add the -hidelegendfrom- option
* Version 1.50 (4Apr2021):  Again attempt to fix the bug in options -lcols()- and -lrows()-
* Version 1.60 (15Jun2021):  Accommodate the graph display options in response to the issue raised here:
*	https://www.statalist.org/forums/forum/general-stata-discussion/general/1610172-grc1leg-ignoring-aspect-ratio

* Version 2.0  (3Mar2022): Revamp to allow scaling of all legend elements with new -legscale()-
*	Set default value of -legscale()- as a function of the number of panels in the combined graph (lines 531-538)
*	Allow user to override the default scaling of all legend elements.
*	Fix bug in -saving()- option in ver. 1.60 where saved .gph file did not incorporate -grc1leg2- edits.
*	When executing option -saving()-, display a clickable message enabling user to view and validate the saved .gph file
*	Add debug options -debug- and -notrap- (undocumented) and -noautosize-. Change dots option to optionally on.

* Version 2.01  (4Mar2022): Made program recursive by adding the modifer "else" at the beginning of lines 223, 234.
* Version 2.02  (4Mar2022): Improve error trapping with -badlegend- subroutine. Subroutine -badlegend- sets graph on before exiting. 
* Version 2.10 (12Mar2022): Add several error traps to attempt to detect and then to avoid or politely exit on encountering a "bad" legend.
*	Use subroutine -chk_legend- to check existence of a legend and pull several legend attributes from -classutil describe-.
* Version 2.11 (13Mar2022): Incomplete legend only disables marker resizing (line 557), not resizing of labels or symbols.
*	Alter warning and error messages accordingly.  Add link to "known issues" when badlegend exits with error.
* Version 2.12 (22Apr2022): Add double compound quotes around `"`legendfrom'"' wherever it appears.
*	Replace = word("`anything'",1) with -gettoken- in line 96
* Version 2.13 (30May2022): Remove error-generating -holes()- option on -gr display- command in line 129.
* Version 2.20 (15Jun2022): Fix option -mtsize()-. For backward compaitibility, keep option -maintitlefrom()-.
*	Add options -mainfrom()-, -subtosubtitle-, -subfrom()-, -stsize()- & -notetonote-, -notefrom()-, -ntsize()-
* Version 2.21 (15Nov2022): Remove the trap requiring -legscale()- options to be absolute numbers 
*	or multiplicative expressions.  (Commented out lines 561-583)  Allows Stata's -graph- engine 
*	to trap errors in the -size()- option and allows the full range of sizing options specified in -help size-.
* Version 2.22 (1Dec2022): Fabio Tufano found that -grc1leg2- would crash when attempting to rescale marker symbols, 
*	if the component graphs have no markers. For example -graph pie- and -graph bar- have no markers.
*	So in line 623 , we only trap an error if _rc ~= 4018.  See help r(4018).
*	Also add column names to the debug matrix -keystyledex- in line 868.
* Version 2.23 (10Dec2022): Add code so that option -hidelegendfrom- is mor elikely to suppress the display of a blank panel
*	in place of the plot named by -legendfrom()-.  Rarely helps.
*	Unnecessary when the hidden panel is that for the last named graph, and user configures the panel layout with -rows()- &/or -cols()-.
*	When all panels are in one row (i.e. -rows(1)-) or the panel to be hidden is one of only three graphs,
*	the -hidelegendfrom- option successfully suppresses the display of the blank panel regardless of its sequence in the list of graphs. 
*	Best to always place the hidden panel last in the list of graphs.
* Version 2.24 (14May2023): NminofKeysLabels substituted for Nkeys in line 603.  
*	 Add _gm_edit ... fill_if_undrawn.set_false in line 243

*	Problem:
	//    Which attributes of a legend predict that -grc1leg2- will fail? 
	//    Problem seems to occur when the -order()- suboption has been used in a component graph to suppress one or more legend keys.
*	Hypothesis #1: 
	//    Resizing legend elements crashes -graph- when the values of -styledex- vary over the keys.
	//    If so, detecting variation among the -styledex- values could be a way to trap 
	//    attempts to resize the legend elements after a legend(order())- option.
*	Possible solution #1:
		//    In the subroutine -chk_legend-, retrieve the value of -sizedex- for each key.
		//    If they vary (that is if `SmlstEqLrgst' == 1), -gr draw- will be unable to create the combined graph with the borrowed legend.
	
*	Hypothesis #2: (adopted in version 2.24)
	//    Resizing legend elements crashes -graph- when the number of labels is smaller than the number of keys
*	Possible solution #1:
		//    In the subroutine -chk_legend-, compute the minimum of Nkeys and Nlabels -> NminofKeysLabels
		//    Loop over only numlist 1/NminofKeysLabels keys and labels, not numlist 1/Nkeys as we did before 
	
*	Condition -labsize-, -lmsize-, -symxsize- & -symysize- on -autosize-

*	Options outside the legend are of two kinds (all seem to work in mem and gph graphs):
*		1.	Options passed to -gr combine- 
*				xcommon, ycommon, holes()
*				xsize(), ysize(), scheme()

*		2.  Options implemented in -grc1leg2- (but are outside the legend):
*				ring(), pos()  
*				legendfrom(), hidelegendfrom
*				lxoffset, lyoffset, xtob1title, ytol1title, y2tor1title

*	Options inside the legend are of two kinds:
*		3.	Options that work in both memory and saved files:
*				labsize() for all labels
*				lmsize() for all markers
*				symxsize() and symysize() for all symbols
*				ltsize(), lsubtsize()
*				legscale() to set default for all of above
*				lholes()                   
*
*		4.	Options that work for memory files BUT ARE LOST IN SAVED FILES
*				lrows(), lcols()
*			a.  Best work-around is to apply these options in component graph,
*				so -grc1leg2- need never rearrange the rows and columns of a legend
*			b.  Alternative is to save with the option -asis- which preserves the edits,
*				but prevents future editing.

*	Sources on Stata class programming for graphics:
*		help class
*		viewsource grc1leg.ado
*		viewsource legend_g.class
*		viewsource legendstyle.class
*		viewsource loggraph_g.class
*		viewsource graph_g.class
*		viewsource global_g.class
*		viewsource _gm_log.ado
*		viewsource _fr_legend_parse_and_log.ado 
*		viewsource gr_current.ado 
